home *** CD-ROM | disk | FTP | other *** search
/ PCGUIA 127 / PC Guia 127.iso / Software / Utils / GParted Live CD / Bin / gparted-livecd-0.2.2.iso / usr_sqfs / bin / autoexpect < prev    next >
Encoding:
Text File  |  2005-07-18  |  7.4 KB  |  345 lines

  1. #!/bin/sh
  2. # \
  3. exec expect -- "$0" ${1+"$@"}
  4. # Name: autoexpect - generate an Expect script from watching a session
  5. #
  6. # Description:
  7. #
  8. # Given a program name, autoexpect will run that program.  Otherwise
  9. # autoexpect will start a shell.  Interact as desired.  When done, exit
  10. # the program or shell.  Autoexpect will create a script that reproduces
  11. # your interactions.  By default, the script is named script.exp.
  12. # See the man page for more info.
  13. #
  14. # Author: Don Libes, NIST
  15. # Date: June 30 1995
  16. # Version: 1.4b
  17.  
  18. set filename "script.exp"
  19. set verbose 1
  20. set conservative 0
  21. set promptmode 0
  22. set option_keys ""
  23.  
  24. proc check_for_following {type} {
  25.     if {![llength [uplevel set argv]]} {
  26.         puts "autoexpect: [uplevel set flag] requires following $type"
  27.         exit 1
  28.     }
  29. }    
  30.  
  31. while {[llength $argv]>0} {
  32.     set flag [lindex $argv 0]
  33.     if {0==[regexp "^-" $flag]} break
  34.     set argv [lrange $argv 1 end]
  35.     switch -- $flag \
  36.       "-c" {
  37.         set conservative 1
  38.     } "-C" {
  39.         check_for_following character
  40.         lappend option_keys [lindex $argv 0] ctoggle
  41.         set argv [lrange $argv 1 end]
  42.     } "-p" {
  43.         set promptmode 1
  44.     } "-P" {
  45.         check_for_following character
  46.         lappend option_keys [lindex $argv 0] ptoggle
  47.         set argv [lrange $argv 1 end]
  48.     } "-Q" {
  49.         check_for_following character
  50.         lappend option_keys [lindex $argv 0] quote
  51.         set argv [lrange $argv 1 end]
  52.     } "-f" {
  53.         check_for_following filename
  54.         set filename [lindex $argv 0]
  55.         set argv [lrange $argv 1 end]
  56.     } "-quiet" {
  57.         set verbose 0
  58.     } default {
  59.         break
  60.     }
  61. }
  62.  
  63. #############################################################
  64. # Variables    Descriptions
  65. #############################################################
  66. # userbuf    buffered characters from user
  67. # procbuf    buffered characters from process
  68. # lastkey    last key pressed by user
  69. #        if undefined, last key came from process
  70. # echoing    if the process is echoing
  71. #############################################################
  72.  
  73. # Handle a character that came from user input (i.e., the keyboard)
  74. proc input {c} {
  75.     global userbuf lastkey
  76.  
  77.     send -- $c
  78.     append userbuf $lastkey
  79.     set lastkey $c
  80. }
  81.  
  82. # Handle a null character from the keyboard
  83. proc input_null {} {
  84.     global lastkey userbuf procbuf echoing
  85.  
  86.     send -null
  87.  
  88.     if {$lastkey == ""} {
  89.         if {$echoing} {
  90.             sendcmd "$userbuf"
  91.         }
  92.         if {$procbuf != ""} {
  93.             expcmd "$procbuf"
  94.         }
  95.     } else {
  96.         sendcmd "$userbuf"
  97.         if {$echoing} {
  98.             expcmd "$procbuf"
  99.             sendcmd "$lastkey"
  100.         }            
  101.     }
  102.     cmd "send -null"
  103.     set userbuf ""
  104.     set procbuf ""
  105.     set lastkey ""
  106.     set echoing 0
  107. }
  108.  
  109. # Handle a character that came from the process
  110. proc output {s} {
  111.     global lastkey procbuf userbuf echoing
  112.  
  113.     send_user -raw -- $s
  114.  
  115.     if {$lastkey == ""} {
  116.         if {!$echoing} {
  117.             append procbuf $s
  118.         } else {
  119.             sendcmd "$userbuf"
  120.             expcmd "$procbuf"
  121.             set echoing 0
  122.             set userbuf ""
  123.             set procbuf $s
  124.         }
  125.         return
  126.     }
  127.  
  128.     regexp (.)(.*) $s dummy c tail
  129.     if {$c == $lastkey} {
  130.         if {$echoing} {
  131.             append userbuf $lastkey
  132.             set lastkey ""
  133.         } else {
  134.             if {$procbuf != ""} {
  135.                 expcmd "$procbuf"
  136.                 set procbuf ""
  137.             }
  138.             set echoing 1
  139.         }
  140.         append procbuf $s
  141.  
  142.         if {[string length $tail]} {
  143.             sendcmd "$userbuf$lastkey"
  144.             set userbuf ""
  145.             set lastkey ""
  146.             set echoing 0
  147.         }
  148.     } else {
  149.         if {!$echoing} {
  150.             expcmd "$procbuf"
  151.         }
  152.         sendcmd "$userbuf$lastkey"
  153.         set procbuf $s
  154.         set userbuf ""
  155.         set lastkey ""
  156.         set echoing 0
  157.     }
  158. }
  159.  
  160. # rewrite raw strings so that can appear as source code but still reproduce
  161. # themselves.
  162. proc expand {s} {
  163.     regsub -all "\\\\" $s "\\\\\\\\" s
  164.     regsub -all "\r" $s "\\r"  s
  165.     regsub -all "\"" $s "\\\"" s
  166.     regsub -all "\\\[" $s "\\\[" s
  167.     regsub -all "\\\]" $s "\\\]" s
  168.     regsub -all "\\\$" $s "\\\$" s
  169.  
  170.     return $s
  171. }
  172.  
  173. # generate an expect command
  174. proc expcmd {s} {
  175.     global promptmode
  176.  
  177.     if {$promptmode} {
  178.         regexp ".*\[\r\n]+(.*)" $s dummy s
  179.     }
  180.  
  181.     cmd "expect -exact \"[expand $s]\""
  182. }
  183.  
  184. # generate a send command
  185. proc sendcmd {s} {
  186.     global send_style conservative
  187.  
  188.     if {$conservative} {
  189.         cmd "sleep .1"
  190.     }
  191.  
  192.     cmd "send$send_style -- \"[expand $s]\""
  193. }
  194.  
  195. # generate any command
  196. proc cmd {s} {
  197.     global fd
  198.     puts $fd "$s"
  199. }
  200.  
  201. proc verbose_send_user {s} {
  202.     global verbose
  203.  
  204.     if {$verbose} {
  205.         send_user -- $s
  206.     }
  207. }
  208.  
  209. proc ctoggle {} {
  210.     global conservative send_style
  211.  
  212.     if {$conservative} {
  213.         cmd "# conservative mode off - adding no delays"
  214.         verbose_send_user "conservative mode off\n"
  215.         set conservative 0
  216.         set send_style ""
  217.     } else {
  218.         cmd "# prompt mode on - adding delays"
  219.         verbose_send_user "conservative mode on\n"
  220.         set conservative 1
  221.         set send_style " -s"
  222.     }
  223. }
  224.  
  225. proc ptoggle {} {
  226.     global promptmode
  227.  
  228.     if {$promptmode} {
  229.         cmd "# prompt mode off - now looking for complete output"
  230.         verbose_send_user "prompt mode off\n"
  231.         set promptmode 0
  232.     } else {
  233.         cmd "# prompt mode on - now looking only for prompts"
  234.         verbose_send_user "prompt mode on\n"
  235.         set promptmode 1
  236.     }
  237. }
  238.  
  239. # quote the next character from the user
  240. proc quote {} {
  241.     expect_user -re .
  242.     send -- $expect_out(buffer)
  243. }
  244.     
  245.  
  246. if {[catch {set fd [open $filename w]} msg]} {
  247.     puts $msg
  248.     exit
  249. }
  250. exec chmod +x $filename
  251. verbose_send_user "autoexpect started, file is $filename\n"
  252.  
  253. # calculate a reasonable #! line
  254. set expectpath /usr/local/bin        ;# prepare default
  255. foreach dir [split $env(PATH) :] {    ;# now look for real location
  256.     if {[file executable $dir/expect] && ![file isdirectory $dir/expect]} {
  257.         set expectpath $dir
  258.         break
  259.     }
  260. }
  261.  
  262. cmd "#![set expectpath]/expect -f
  263. #
  264. # This Expect script was generated by autoexpect on [timestamp -format %c]
  265. # Expect and autoexpect were both written by Don Libes, NIST."
  266. cmd {#
  267. # Note that autoexpect does not guarantee a working script.  It
  268. # necessarily has to guess about certain things.  Two reasons a script
  269. # might fail are:
  270. #
  271. # 1) timing - A surprising number of programs (rn, ksh, zsh, telnet,
  272. # etc.) and devices discard or ignore keystrokes that arrive "too
  273. # quickly" after prompts.  If you find your new script hanging up at
  274. # one spot, try adding a short sleep just before the previous send.
  275. # Setting "force_conservative" to 1 (see below) makes Expect do this
  276. # automatically - pausing briefly before sending each character.  This
  277. # pacifies every program I know of.  The -c flag makes the script do
  278. # this in the first place.  The -C flag allows you to define a
  279. # character to toggle this mode off and on.
  280.  
  281. set force_conservative 0  ;# set to 1 to force conservative mode even if
  282.               ;# script wasn't run conservatively originally
  283. if {$force_conservative} {
  284.     set send_slow {1 .1}
  285.     proc send {ignore arg} {
  286.         sleep .1
  287.         exp_send -s -- $arg
  288.     }
  289. }
  290.  
  291. #
  292. # 2) differing output - Some programs produce different output each time
  293. # they run.  The "date" command is an obvious example.  Another is
  294. # ftp, if it produces throughput statistics at the end of a file
  295. # transfer.  If this causes a problem, delete these patterns or replace
  296. # them with wildcards.  An alternative is to use the -p flag (for
  297. # "prompt") which makes Expect only look for the last line of output
  298. # (i.e., the prompt).  The -P flag allows you to define a character to
  299. # toggle this mode off and on.
  300. #
  301. # Read the man page for more info.
  302. #
  303. # -Don
  304.  
  305. }
  306.  
  307. cmd "set timeout -1"
  308. if {$conservative} {
  309.     set send_style " -s"
  310.     cmd "set send_slow {1 .1}"
  311. } else {
  312.     set send_style ""
  313. }
  314.  
  315. if {[llength $argv]>0} {
  316.     eval spawn -noecho $argv
  317.     cmd "spawn $argv"
  318. } else {
  319.     spawn -noecho $env(SHELL)
  320.     cmd "spawn \$env(SHELL)"
  321. }
  322.  
  323. cmd "match_max 100000"
  324.  
  325. set lastkey ""
  326. set procbuf ""
  327. set userbuf ""
  328. set echoing 0
  329.  
  330. remove_nulls 0
  331.  
  332. eval interact $option_keys {
  333.     -re . {
  334.     input $interact_out(0,string)
  335.     } -o -re .+ {
  336.     output $interact_out(0,string)
  337.     } eof {
  338.     cmd "expect eof"
  339.     return
  340.     }
  341. }
  342.  
  343. close $fd
  344. verbose_send_user "autoexpect done, file is $filename\n"
  345.